CSS Hack
- 什么是 CSS Hack
- Hack 即不合法但生效的写法
- 主要用于解决不同浏览器或不同浏览器版本之间的兼容性问题
- CSS Hack 的分类
- CSS Hack 的优缺点
- 难理解、难维护、不稳定
- 替代方案
- 特性检测
- 针对性加 class
什么是 CSS Hack
- CSS hack 主要用于解决不同浏览器或不同浏览器版本之间的兼容性问题。这些问题可能导致在不同浏览器上呈现相同网页不一致。
- CSS hacks 是通过利用不同浏览器的解析差异来实现特定样式效果的方法。
- 但需要注意的是,使用 CSS hack 并不是一种推荐的做法,因为它们可能会使代码复杂,难以维护,而且不稳定,因为浏览器的行为可能会随着时间的推移而变化。
CSS Hack 的分类
-
CSS 属性前缀法:利用不同浏览器对某些 CSS 属性识别的差异,添加浏览器前缀实现 hack。比如
-webkit-、-moz-、-ms-、-o-等。.box { -webkit-transform: rotate(30deg); -moz-transform: rotate(30deg); -ms-transform: rotate(30deg); transform: rotate(30deg); } -
IE 条件注释法:IE 支持根据版本对 CSS 进行条件注释解析,可以针对 IE 添加样式。
<!--[if IE 8]> <link rel="stylesheet" type="text/css" href="ie8.css"> <![endif]--> -
选择器 hack:不同浏览器对某些选择器的识别支持不同,比如 IE6-7 不识别
:first-child选择器。.box :first-child { color: red; } body:nth-of-type(1) .iehack { color: #f00; /* 对 Windows IE9/Firefox 7+/Opera 10+/所有 Chrome/Safari 的 CSS hack,选择器也适用几乎全部 Mobile/Linux/Mac browser*/ } -
CSS 属性值 hack:不同浏览器对应某些属性值解析不同,比如 IE6 对
display:inline-block不识别,但识别_display:inline; zoom:1。.box { display: inline; zoom: 1; } .element { background-color: orange; /* all IE/FF/CH/OP*/ } .element { *background-color: blue; /* IE6+7, doesn't work in IE8/9 as IE7 */ } .element { _background-color: red; /* IE6 */ } .element { background-color: green\0; /* IE8+9+10 */ } :root .element { background-color: pink\0; } /* IE9+10 */ -
CSS 属性 hack:某些属性不同浏览器支持不同,比如 IE6-7 支持
_width,Chrome 支持-webkit-text-size-adjust。.hacktest { background-color: blue; /* 都识别,此处针对 firefox */ background-color: red\9; /*all ie*/ background-color: yellow\0; /*for IE8/IE9/10 最新版 opera 也认识*/ +background-color: pink; /*for ie6/7*/ _background-color: orange; /*for ie6*/ } -
媒体查询 Hack:使用媒体查询可以根据屏幕宽度或其他条件应用不同的样式,
@media screen and (min-width: 0) { .hacktest { background-color: black\0; } /*opera*/ } @media screen and (min-width: 0) { .hacktest { background-color: purple\9; } /* for IE9/IE10 PS:国外有些习惯常写作\0,根本没考虑 Opera 也认识\0的实际 */ } @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { .hacktest { background-color: green; } /* for IE10+ 此写法可以适配到高对比度和默认模式,故可覆盖所有 ie10 的模式 */ } @media screen and (-webkit-min-device-pixel-ratio: 0) { .hacktest { background-color: gray; } } /*for Chrome/Safari*/
CSS Hack 的缺点
- 不优雅:CSS Hack 需要针对不同浏览器编写不同的样式代码,不仅增加了代码量,也使代码变得不够简洁和优雅。
- 维护困难:针对不同浏览器编写 hack 代码会使维护变得非常困难。代码变得复杂且冗余,不利于后期的修改和扩展。
- 不稳定,容易被新浏览器覆盖:针对旧浏览器的 hack 可能被新浏览器的标准特性和功能覆盖,导致 hack 失效。需要持续更新 hack 代码。
- 难理解,开发体验较差:编写及维护 hack 代码的过程令开发者感到痛苦,开发体验较差。
替代方案
- 特性检测:通过 JavaScript 检测浏览器是否支持某些特性,从而决定是否应用某些样式。这种方式可以避免使用 hack,但需要编写额外的 JavaScript 代码。
- 针对性加 class:通过针对性地为不同浏览器添加 class,从而为不同浏览器编写不同的样式。这种方式可以避免使用 hack,但需要编写额外的 HTML 和 CSS 代码。
<!DOCTYPE html>
<html>
<head>
<style>
.my-element {
/* 共用样式 */
width: 200px;
height: 100px;
background-color: lightgray;
}
.flexbox-supported .my-element {
/* 适用于支持 Flexbox 的浏览器 */
display: flex;
justify-content: center;
align-items: center;
}
.flexbox-not-supported .my-element {
/* 适用于不支持 Flexbox 的浏览器 */
display: block;
text-align: center;
line-height: 100px;
}
</style>
</head>
<body>
<div class="my-element">This is a flexible element.</div>
<script>
function isFlexboxSupported() {
const element = document.createElement("div");
element.style.display = "flex";
return element.style.display === "flex";
}
if (isFlexboxSupported()) {
document.body.classList.add("flexbox-supported");
} else {
document.body.classList.add("flexbox-not-supported");
}
</script>
</body>
</html>
样式书写顺序
- 通用样式放在前面:首先,编写适用于所有浏览器的通用样式规则,这些规则不依赖于特定的浏览器或条件。这将是代码的基本样式。
- 特定浏览器的 hack 样式:在通用样式之后,添加任何特定于浏览器的 hack 样式。这些样式应该在通用样式之后,以便在通用样式适用时,不被 hack 样式覆盖。
/* 通用样式 */
.my-element {
background-color: lightgray;
}
/* IE hack */
* html .my-element {
background-color: blue;
}